package com.huangmingfu;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: 黄名富
 * @Description: 缓存代理
 */
public class CacheProxy {

    private static class CacheMethodInterceptor implements MethodInterceptor {

        private final static Map<MethodKey,Object> resultMap = new HashMap<>();

        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            MethodKey methodKey = MethodKey.getKey(method, args);
            Object result = resultMap.get(methodKey);
            if (result != null) {
                return result;
            } else {
                Object result2 = methodProxy.invokeSuper(o, args);
                resultMap.put(methodKey,result2);
                return result2;
            }
        }
    }

    // 根据method 及 参数来生成key
    private static class MethodKey {

        private static final Map<String,MethodKey> methodKeyMap = new HashMap<>();

        private String code;

        private MethodKey(String code) { this.code = code;}

        public static MethodKey getKey(Method method, Object[] objects) {
            String hasCode = "method:" + method.hashCode();
            if (objects != null) hasCode += "args:" + Arrays.hashCode(objects);
            MethodKey methodKey = methodKeyMap.get(hasCode);
            if (methodKey == null) {
                synchronized (MethodKey.class) {
                    methodKey = new MethodKey(hasCode);
                    methodKeyMap.put(hasCode,methodKey);
                }
            }
            return methodKey;
        }

        @Override
        public String toString() {
            return code;
        }
    }

    private static class ComplexCompute {

        public ComplexCompute() {
        }

        long compute(long num) {
            System.out.println("执行复杂计算，参数" + num);
            return num * 2345;
        }
    }

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(ComplexCompute.class);
        enhancer.setCallback(new CacheMethodInterceptor());
        ComplexCompute compute = (ComplexCompute) enhancer.create();
        System.out.println(compute.compute(23));
        System.out.println("----------");
        System.out.println(compute.compute(123));
        System.out.println("----------");
        System.out.println(compute.compute(23));
    }

}
